<?php


namespace services\clinic;

use Yii;
use common\models\clinic\Clinic;
use common\helpers\ImageHelper;
use common\models\member\Attr;
use common\components\Service;
use common\models\clinic\Project;
use common\models\clinic\ProjectBind;
use common\models\clinic\UserSurplus;
use common\models\clinic\UserTreatment;
use common\models\clinic\UserTreatmentDetail;
use common\models\patient\User;
use yii\db\Expression;
use common\helpers\CommonHelper;

class TreatmentPatientService extends Service
{
    /**
     * 治疗-患者列表
     *
     * @param $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getList($params, $page, $pageSize)
    {
        // 诊室或者治疗时间存在则查询患者治疗表
        if (
            (isset($params['clinic_project_id']) && $params['clinic_project_id']) ||
            (isset($params['start_time']) && $params['start_time']) ||
            (isset($params['end_time']) && $params['end_time'])
        ) {
            return $this->getSearchList($params, $page, $pageSize);
        }
        // 否则按照患者表查询
        $query = User::find()
            ->alias('a')
            ->select([
                'patient_card_id', 'name', 'age', 'gender', 'clinic_id',
                // new Expression('FROM_UNIXTIME(`last_clinic_time`, "%Y-%m-%d %H:%i") last_clinic_time'),
                'last_clinic_time'
            ])
            ->where(['project_id' => $params['project_id'], 'status' => [User::STATUS_ENABLE, User::STATUS_INVALID]]);

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere(['patient_card_id' => trim($params['keywords'])]);
            }
        }

        // 诊室
        isset($params['clinic_id']) && $params['clinic_id'] && $query->andWhere(['clinic_id' => $params['clinic_id']]);

        // 就诊类型
        isset($params['outpatient_type']) && $params['outpatient_type'] && $query->andWhere(['outpatient_type_id' => $params['outpatient_type']]);
        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query
            ->orderBy(['last_clinic_time' => SORT_DESC])
            ->asArray()
            ->all();
        if ($list) {

            // 最新患者治疗ID
            $treatmentList = UserTreatment::find()
                ->alias('a')
                ->select([new expression("MAX(a.id) as id")])
                ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b.patient_card_id')
                ->where([
                    'a.project_id' => $params['project_id'],
                    'b.project_id' => $params['project_id'],
                    'b.status' => User::STATUS_ENABLE,
                    'a.patient_card_id' => array_column($list, 'patient_card_id')
                ])
                ->groupBy('a.patient_card_id')
                ->asArray()
                ->all();

            // 患者最新治疗信息
            $treatmentList = UserTreatment::find()
                ->select(['clinic_project_name', 'operate_name', 'patient_card_id'])
                ->where(['id' => array_column($treatmentList, 'id')])
                ->asArray()
                ->all();

            $tlArr = [];
            foreach ($treatmentList as $tl) {
                $tlArr[$tl['patient_card_id']] = $tl;
            }

            // 信息修改
            foreach ($list as $key => &$val) {
                $val['gender'] = User::$genders[$val['gender']];
                $clinicIs = Clinic::findOne(['id' => $val['clinic_id']]);
                $val['clinic_name'] = '';
                if ($clinicIs) {
                    $val['clinic_name'] = $clinicIs->name;
                }
                $val['recently_clinic_time'] = $val['last_clinic_time'] ? date('Y-m-d H:i:s', $val['last_clinic_time']) : '';

                if (isset($tlArr[$val['patient_card_id']])) {
                    $list[$key] = $val + $tlArr[$val['patient_card_id']]; // 治疗数据与患者信息合并
                } else {
                    $val['clinic_project_name'] = '';
                    $val['operate_name'] = '';
                }
            }
        }
        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];

    }

    public function getSearchList($params, $page = 1, $pageSize = 10)
    {
        // 获取最新治疗数据ID
        $query = UserTreatment::find()
            ->alias('a')
            ->select(['a.patient_card_id', new expression("MAX(a.id) as id"), 'b.name', 'b.age', 'b.gender', 'b.clinic_id'])
            ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b.patient_card_id')
            ->where([
                'a.project_id' => $params['project_id'],
                'b.status' => [User::STATUS_ENABLE, User::STATUS_INVALID]
            ])
            ->groupBy('a.patient_card_id');

        // 日期
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'a.recently_clinic_time', strtotime($params['start_time'])]);
        }
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'a.recently_clinic_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        // 治疗项目
        isset($params['clinic_project_id']) && $params['clinic_project_id'] && $query->andWhere(['a.clinic_project_id' => $params['clinic_project_id']]);

        // 诊室
        isset($params['clinic_id']) && $params['clinic_id'] && $query->andWhere(['b.clinic_id' => $params['clinic_id']]);

        // 就诊类型
        isset($params['outpatient_type']) && $params['outpatient_type'] && $query->andWhere(['b.outpatient_type_id' => $params['outpatient_type']]);

        $list = $query
            ->asArray()
            ->all();

        // 患者最新治疗数据
        $treatmentList = UserTreatment::find()
            ->select([
                'id', 'clinic_project_name', 'operate_name',
                new Expression('FROM_UNIXTIME(`recently_clinic_time`, "%Y-%m-%d %H:%i") recently_clinic_time'),
            ])
            ->where(['id' => array_column($list, 'id')]);// 总数
        $total = $treatmentList->count();

        // 分页
        if ($page && $pageSize) {
            $treatmentList->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $treatmentList = $treatmentList
            ->orderBy(['recently_clinic_time' => SORT_DESC])
            ->asArray()
            ->all();

        if ($list) {
            $valArr = [];
            foreach ($list as &$val) {
                $val['gender'] = User::$genders[$val['gender']];
                $clinicIs = Clinic::findOne(['id' => $val['clinic_id']]);
                $val['clinic_name'] = $clinicIs->name;
                $valArr[$val['id']] = $val;
            }
            foreach ($treatmentList as $key => &$tl) {
                if ($valArr[$val['id']]) {
                    $treatmentList[$key] = $tl + $valArr[$tl['id']]; // 治疗数据与患者信息合并
                }
            }
        }
        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $treatmentList,
        ];
    }


    /**
     * 患者治疗列表（详细，包含新增和退费）
     *
     * @param $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getTreatmentList($params, $page = 1, $pageSize = 10)
    {
        // 患者治疗列表
        $query = UserTreatment::find()
            ->select([
                'id', 'clinic_project_name', 'recently_clinic_num', 'recently_surplus_num',
                new Expression('FROM_UNIXTIME(`recently_clinic_time`, "%Y-%m-%d %H:%i") recently_clinic_time'),
                'total_num', 'help_num', 'operate_name', 'type', 'patient_signature', 'clinic_project_id',
                'clinic_name', 'patient_card_id'
            ])
            ->where([
                'project_id' => $params['project_id'],
                'patient_card_id' => $params['patient_card_id'],
            ]);

        // 治疗项目
        isset($params['clinic_project_id']) && $params['clinic_project_id'] && $query->andWhere(['clinic_project_id' => $params['clinic_project_id']]);

        // 日期
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'recently_clinic_time', strtotime($params['start_time'])]);
        }
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'recently_clinic_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query
            ->orderBy(['created_at' => SORT_DESC, 'id' => SORT_DESC])
            ->asArray()
            ->all();

        foreach ($list as &$val) {
            $template = Project::findOne(['id' => $val['clinic_project_id']]);
            $val['num'] = $val['recently_clinic_num'] + $val['recently_surplus_num'];
            $val['template'] = $template ? $template->template : '';
            $val['type_name'] = $val['type'] ? UserTreatment::$type[$val['type']] : '';
            $val['type'] = $val['type'];
            unset($val['recently_clinic_num']);
            unset($val['recently_surplus_num']);
        }

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];

    }

    /**
     * 患者治疗项目数量
     *
     * @param $params
     * @return array|\yii\db\ActiveRecord[]
     */
    public function getPatientSurplus($params)
    {
        return UserSurplus::find()
            ->select('clinic_project_name, clinic_project_id, total_num, help_num')
            ->where(['patient_card_id' => $params['patient_card_id'], 'project_id' => $params['project_id']])
            ->asArray()
            ->all();
    }

    /**
     * 患者基本信息
     *
     * @Interface getPatientDetail
     * @param $params
     * @return array|null|\yii\db\ActiveRecord
     */
    public function getPatientDetail($params)
    {
        $userIs = User::find()
            ->select('id, patient_card_id, name, gender, age')
            ->where(['patient_card_id' => $params['patient_card_id'], 'project_id' => $params['project_id']])
            ->asArray()
            ->one();
        $userIs['gender'] = User::$genders[$userIs['gender']];
        return $userIs;
    }

    /**
     * 治疗详情
     *
     * @param $id
     * @return array|\yii\db\ActiveRecord[]
     */
    public function treatmentDetail($id)
    {
        return UserTreatmentDetail::find()
            ->select('body_parts_large_name, body_parts_small_name, num, dose')
            ->where(['clinic_treatment_id' => $id])
            ->asArray()
            ->all();
    }

    /**
     * 治疗信息
     *
     * @param $id 治疗ID
     * @return array
     */
    public function treatment($id)
    {
        $userTreatment = UserTreatment::find()
            ->select([
                new Expression('FROM_UNIXTIME(`recently_clinic_time`, "%Y-%m-%d %H:%i") recently_clinic_time'),
                'recently_clinic_num', 'recently_surplus_num', 'total_num', 'help_num', 'patient_signature', 'remark', 'clinic_project_id'
            ])
            ->where(['id' => $id])
            ->asArray()
            ->one();
        $list = [
            'recently_num' => $userTreatment['recently_clinic_num'] + $userTreatment['recently_surplus_num'],
            'num' => $userTreatment['total_num'] + $userTreatment['help_num'],
            'recently_clinic_time' => $userTreatment['recently_clinic_time'],
            'patient_signature' => ImageHelper::getImageUrl($userTreatment['patient_signature']),
            'remark' => $userTreatment['remark'],
        ];
        return $list;
    }

    /**
     * 患者治疗项目数量
     *
     * @param $params
     * @return array
     */
    public function getTreatmentNum($params)
    {
        $where = [];
        if (isset($params['clinic_project_name']) && $params['clinic_project_name']) {
            $where = ['like', 'a.name', $params['clinic_project_name']];
        }

        // 已绑定治疗室的治疗项目
        $clinicProjectList = Project::find()
            ->select('a.name, a.id')
            ->alias('a')
            ->innerJoin(ProjectBind::tableName() . ' b', 'a.id = b.clinic_project_id')
            ->where(['and', $where, ['a.project_id' => $params['project_id'], 'a.status' => Project::STATUS_ENABLE]])
            ->orderBy(['a.sort' => SORT_ASC, 'a.created_at' => SORT_ASC])
            ->asArray()
            ->all();

        // 已绑定治疗室的治疗项目
        $clinicProject = array_column($clinicProjectList, 'name', 'id');

        // 患者存在的治疗项目
        $patientClinicProject = UserSurplus::find()
            ->select('id, clinic_project_id, clinic_project_name, total_num, help_num')
            ->where(['patient_card_id' => $params['patient_card_id'], 'project_id' => $params['project_id']])
            ->asArray()
            ->all();

        $pcpList = [];

        // 先给所有治疗项目数量赋值
        foreach ($clinicProject as $k => $cp) {
            $pcpList[$k] = [
                'clinic_project_id' => $k,
                'clinic_project_name' => $cp,
                'total_num' => 0,
                'help_num' => 0,
            ];
        }

        // 更新患者存在的治疗项目的数量
        foreach ($patientClinicProject as $pcp) {
            if (isset($pcpList[$pcp['clinic_project_id']])) {
                $pcpList[$pcp['clinic_project_id']] = [
                    'clinic_project_id' => $pcp['clinic_project_id'],
                    'clinic_project_name' => $pcp['clinic_project_name'],
                    'total_num' => $pcp['total_num'],
                    'help_num' => $pcp['help_num'],
                ];
            }
        }

        $list = array_values($pcpList);
        return $list;
    }

    /**
     * 新增治疗项目数量
     *
     * @param $params
     * @return array|mixed
     */
    public function addTreatNum($params)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 治疗项目名称
            $clinicProject = Project::findOne(['id' => $params['clinic_project_id']]);

            // 查找患者是否有治疗项目
//            $patientSurplusIs = UserSurplus::findOne([
//                'project_id' => $params['project_id'],
//                'patient_card_id' => $params['patient_card_id'],
//                'clinic_project_id' => $params['clinic_project_id'],
//            ]);

            // 没有明确主键,这个是表级别锁
            $patientSurplusIs = UserSurplus::find()
                ->where("project_id = $params[project_id] and patient_card_id = '$params[patient_card_id]' and clinic_project_id = $params[clinic_project_id] for update")
                ->one();

            // 治疗项目新增数据
            self::clinicUserTreatment(UserTreatment::TYPE_ADD, $params, $clinicProject->name, $patientSurplusIs);

            // 患者信息
            $patientIs = User::findOne([
                'project_id' => $params['project_id'],
                'patient_card_id' => $params['patient_card_id'],
                'status' => User::STATUS_ENABLE
            ]);

            // 不存在该治疗项目则新增
            if (!$patientSurplusIs) {
                $patientSurplusIs = new UserSurplus();
                $patientSurplusIs->project_id = $params['project_id'];
                $patientSurplusIs->patient_card_id = $params['patient_card_id'];
                $patientSurplusIs->clinic_project_id = $params['clinic_project_id'];
                $patientSurplusIs->total_num = $params['total_num'];
                $patientSurplusIs->help_num = $params['help_num'];
            } else {
                $patientSurplusIs->total_num = $params['total_num'] + $patientSurplusIs->total_num;
                $patientSurplusIs->help_num = $params['help_num'] + $patientSurplusIs->help_num;
            }
            $patientSurplusIs->name = $patientIs->name;
            $patientSurplusIs->clinic_project_name = $clinicProject->name;
            $patientSurplusIs->save();

            $transaction->commit();
            return ['id' => $patientSurplusIs->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 退费（减少治疗项目数量）
     *
     * @param $params
     * @return array|mixed
     */
    public function refundTreatNum($params)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 治疗项目名称
            $clinicProject = Project::findOne(['id' => $params['clinic_project_id']]);

            // 查找患者是否有治疗项目
            $patientSurplusIs = UserSurplus::findOne([
                'project_id' => $params['project_id'],
                'patient_card_id' => $params['patient_card_id'],
                'clinic_project_id' => $params['clinic_project_id'],
            ]);

            // 治疗项目退费数据
            self::clinicUserTreatment(UserTreatment::TYPE_REDUCE, $params, $clinicProject->name, $patientSurplusIs);

            // 患者信息
            $patientIs = User::findOne([
                'project_id' => $params['project_id'],
                'patient_card_id' => $params['patient_card_id']
            ]);

            $patientSurplusIs->total_num = $patientSurplusIs->total_num - $params['total_num'];
            $patientSurplusIs->help_num = $patientSurplusIs->help_num - $params['help_num'];
            $patientSurplusIs->name = $patientIs->name;
            $patientSurplusIs->clinic_project_name = $clinicProject->name;
            $patientSurplusIs->save();

            $transaction->commit();
            return ['id' => $patientSurplusIs->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 新增治疗详细（新增 / 退费）
     *
     * @param $type 2=新增 3=退费
     * @param $params
     * @param $clinicProjectName 项目名称
     * @param $patientSurplusIs
     * @return array
     */
    public function clinicUserTreatment($type, $params, $clinicProjectName, $patientSurplusIs)
    {
        $model = new UserTreatment();
        $model->project_id = $params['project_id'];
        $model->treatment_room_id = 0;
        $model->patient_card_id = $params['patient_card_id'];
        $model->clinic_project_id = $params['clinic_project_id'];
        $model->clinic_project_name = $clinicProjectName;
        $model->recently_clinic_time = time();
        $model->recently_clinic_num = $params['total_num'];
        $model->recently_surplus_num = $params['help_num'];

        if ($type == UserTreatment::TYPE_ADD) {
            if ($patientSurplusIs) {
                $totalNum = $params['total_num'] + $patientSurplusIs->total_num;
                $helpNum = $params['help_num'] + $patientSurplusIs->help_num;
            } else {
                $totalNum = $params['total_num'];
                $helpNum = $params['help_num'];
            }
        } else {
            $totalNum = $patientSurplusIs->total_num - $params['total_num'];
            $helpNum = $patientSurplusIs->help_num - $params['help_num'];
        }
        $model->total_num = $totalNum;
        $model->help_num = $helpNum;

        // 患者信息
        $patientIs = User::find()
            ->alias('a')
            ->select('b.name as clinic_name, a.clinic_id')
            ->leftJoin(Clinic::tableName() . ' b', 'a.clinic_id = b.id')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.patient_card_id' => $params['patient_card_id'],
                'a.status' => User::STATUS_ENABLE
            ])
            ->asArray()
            ->one();

        $model->clinic_id = $patientIs ? $patientIs['clinic_id'] : 0;
        $model->clinic_name = $patientIs ? $patientIs['clinic_name'] : '';
        $model->operate_id = $params['member_id'];

        $memberAttr = Attr::findOne(['member_id' => $params['member_id']]);
        $model->operate_profession = $memberAttr ? $memberAttr->profession_name : '';
        $model->operate_name = $params['member_name'];

        $model->patient_signature = '';
        $model->type = $type;
        $model->remark = '';
        if ($model->save() == false) {
            return ['code' => 422, 'message' => '操作失败'];
        }
        return ['code' => 200, 'message' => '操作成功'];
    }
}
